Physical devices interconnected in a computer system frequently utilize an interrupt as a mechanism for indicating the occurrence of certain events. An interrupt generally comprises a signal, transmitted from a device to a processor in the computer system, requesting attention from the processor. For example, a network adapter, coupled to the processor, may generate, via a network controller, a receive interrupt upon receiving an incoming packet from a network (a packet generally comprises a package of information transmitted as a unit in synchronous communications). The receive interrupt is intended to indicate to the processor that a new packet has arrived from the network, and to identify a location in a memory from which the packet may be retrieved.
At system initialization, a device driver—a software component that permits a computer system to communicate with a device and often manipulates data in order to transmit data to the device—allocates a plurality of receive packet buffers and identifies the location of the buffers in host memory to the network controller. As packets arrive from the network, the network controller transfers the incoming packets to the packet buffers allocated by the device driver at initialization, and generates the receive interrupt to indicate that new packets have arrived.
The network adapter, also commonly referred to as a network interface card, comprises an expansion card, or similar device, used to provide network access to a computer system, or other device (e.g., a printer), and to mediate between the computer system and the physical media, such as cabling or the like, over which network transmissions (e.g., packets) travel. Receipt of the receive interrupt by the processor triggers the execution of an interrupt handler (generally a function of the device driver) for processing the newly arrived packet, as well as other packets which may have arrived during a scheduling latency created as the processor completes its current tasks and switches contexts to execute the interrupt handler. The interrupt handler comprises a special routine executed when a specific interrupt occurs, and which includes instructions for dealing with the particular situation that caused the interrupt. The interrupt handler examines the network controller to determine the cause of the interrupt, for instance, the receipt of new packets from the network, and indicates the newly arrived packets to a protocol stack for processing. The protocol stack comprises a set of protocols (e.g., Transmission Control Protocol/Internet Protocol (“TCP/IP”)) that work together on different levels to enable communication on a network. When the protocol stack finishes processing a packet, the packet buffer is returned to the device driver to be used for subsequent packets.
Each interrupt, and the execution of the interrupt handler, introduces an amount of “overhead” to the computer system's processor. The overhead comprises work or information that provides support for a computing process, but is not an intrinsic part of the operation or data. For example, with each incoming packet, the processor may need to send a signal comprising the packet, over a bus, or otherwise transfer the packet to one or more other components of the computer system. This overhead may significantly impact processing time, especially in the context of modern operating systems, such as Windows NT®, or Windows® 2000.
After the protocol stack has been given several packets to process, interrupts generated by the network controller indicating the arrival of new packets from the network interfere with the processing operations for the packets currently indicated to the protocol stack. These interrupts delay the processing of the previously indicated packets by causing the processor to stop executing work for the protocol stack, and to instead process the interrupts. In severe circumstances, often referred to as “interrupt storms,” the receive interrupts can be so numerous as to prevent the protocol stack from making any forward progress in the processing operations of the currently indicated packets, many times resulting in dropped packets. This situation, in which forward progress has been effectively stopped, is referred to as “live-lock.”
Methods exist for detecting when “live-lock” is likely to occur, and for disabling the generation of receive interrupts from network controllers in response to this condition. However, these methods then typically rely on a polling process to periodically determine the status of each device in order to indicate new packets to the protocol stack. Because polling rates are not easily constrained in, for example, a Windows® operating system, the rate of indication of new packets to the protocol stack may continue to outpace the protocol stack's packet-processing rate, thereby overrunning the protocol stack's queues, and causing packets to be dropped. On the other hand, in certain situations, waiting for a polling timer to complete a cycle may increase latency of packets unnecessarily. Latency refers to the period of time that passes between the arrival of a packet at the network adapter, and execution of the interrupt handler.
While a static indication policy may be optimized for a particular ideal workload, as runtime workload shifts away from the ideal workload, the static policy may degrade overall system performance, thereby resulting in dropped packets (e.g., if packets are indicated too often), or poor response latency (e.g., if packets are not indicated often enough).